package com.hoshiicloud.shxping.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hoshiicloud.common.controller.BaseController;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.common.utils.AESUtil;
import com.hoshiicloud.common.utils.LBSUtil;
import com.hoshiicloud.saleorder.dto.OrderDTO;
import com.hoshiicloud.saleorder.entity.OrderMain;
import com.hoshiicloud.saleorder.param.OrderMainQueryParam;
import com.hoshiicloud.saleorder.param.RefundOrderPayParam;
import com.hoshiicloud.shxping.dto.ConsumerDto;
import com.hoshiicloud.shxping.dto.MemberDto;
import com.hoshiicloud.shxping.dto.PayResultDTO;
import com.hoshiicloud.shxping.dto.PlatStoreDTO;
import com.hoshiicloud.shxping.feign.IUserFeignService;
import com.hoshiicloud.shxping.feign.IdGeneratorService;
import com.hoshiicloud.shxping.feign.OrderFeignService;
import com.hoshiicloud.shxping.feign.VeriCenterFeignService;
import com.hoshiicloud.shxping.param.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yangcheng
 * @version 1.0
 * @title: OrderController
 * @description: 订单Controller
 * @date 2019/6/10 0:35
 * @mail maiboyc@163.com
 */
@Slf4j
@RestController
@RequestMapping("/order")
@Api(value = "订单管理", tags = {"订单相关操作接口"}, produces = MediaType.APPLICATION_JSON_VALUE)
public class OrderController extends BaseController {
    @Resource
    private IdGeneratorService idGeneratorService;

    // 订单微服务Service
    @Resource
    private OrderFeignService orderFeignService;

    // 用户微服务Service
    @Resource
    private IUserFeignService userFeignService;

    // 验证中心微服务Service
    @Resource
    private VeriCenterFeignService veriCenterFeignService;

    /**
     * 提交订单
     * @param param 提交订单参数
     * @return Response
     */
    @PostMapping("/submit")
    @ApiOperation(value = "提交订单", notes = "提交订单", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response submit(@RequestBody OrderSubmitParam param) {
        Response rs;
        try {
            rs = orderFeignService.submitOrder(param);
        } catch (Exception e) {
            log.error("提交订单异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("提交订单异常" + e.getMessage());
        }
        return rs;
    }

    /**
     * 支付订单
     * @param param 支付参数
     * @return Response
     */
    @PostMapping("/pay")
    @ApiOperation(value = "支付订单", notes = "支付订单", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<PayResultDTO> pay(@RequestBody PayOrderParam param) {
        Response<PayResultDTO> rs;
        ConsumerDto consumerDto;
        try {
            //支付模式为xxx 支付方式为xxx的时候 才需要openid todo
            Response<ConsumerDto> rsp = userFeignService.getConsumerById(param.getUserId());
            if (rsp != null && rsp.getData() != null) {
                consumerDto = rsp.getData();
                Response<MemberDto> rspMember = userFeignService.getMemberById(consumerDto.getMemberId());
                if (rspMember != null && rspMember.getData() != null) {
                    MemberDto memberDto = rspMember.getData();
                    param.setOpenId(memberDto.getWxOpenId());
                    Response<PayResultDTO> pay_rs = orderFeignService.payOrder(param);
                    if (null != pay_rs && pay_rs.getCode() == 200 && null != pay_rs.getData()) {
                        rs = pay_rs;
                        // 同时更新用户默认店铺，方便下次直接展示最近购买店铺
                        Response<OrderDTO> orderResponse = orderFeignService.viewOrder(param.getOrderId());
                        if (null != orderResponse && orderResponse.getCode() == 200 && null != orderResponse.getData()) {
                            consumerDto.setStoreId(orderResponse.getData().getStoreId());
                            userFeignService.updateConsumer(consumerDto);
                        }
                    } else {
                        rs = Response.failed(String.format("支付订单失败：%s", pay_rs != null ? pay_rs.getMsg() : null));
                    }
                } else {
                    rs = Response.failed("没有查询到对应的平台消费者信息");
                }
            } else {
                rs = Response.failed("没有查询到对应的注册会员信息");
            }
        } catch (Exception e) {
            log.error("支付订单异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("支付订单异常" + e.getMessage());
        }
        return rs;
    }


    /**
     * 取消订单
     * @param orderId 订单ID
     * @return Response
     */
    @DeleteMapping("/cancel/{orderId}")
    @ApiOperation(value = "取消订单", notes = "取消订单", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response cancel(@PathVariable("orderId") Long orderId) {
        Response rs;
        try {
            // 判断下单时间
            rs = orderFeignService.cancelOrder(orderId);
        } catch (Exception e) {
            log.error("取消订单异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("取消订单异常" + e.getMessage());
        }
        return rs;
    }

    /**
     * 退款订单
     * @param param 退款參數
     * @return Response
     */
    @PostMapping("/refund")
    @ApiOperation(value = "退款订单", notes = "退款订单", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response refund(@RequestBody @Valid RefundOrderPayParam param) {
        Response rs;
        try {
            param.setRefundId(Long.valueOf(idGeneratorService.queryGeneratorId()));
            rs = orderFeignService.refundOrder(param);
        } catch (Exception e) {
            log.error("退款订单异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("退款订单异常" + e.getMessage());
        }
        return rs;
    }

    /**
     * 删除订单
     * @param orderId 订单ID
     * @return Response
     */
    @DeleteMapping("/delete/{orderId}")
    @ApiOperation(value = "删除订单", notes = "删除订单", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response delete(@PathVariable("orderId") Long orderId) {
        Response rs;
        try {
            rs = orderFeignService.deleteOrder(orderId);
        } catch (Exception e) {
            log.error("删除订单异常" + "[" + e.getMessage() + "]");
            rs = Response.failed("删除订单异常" + e.getMessage());
        }
        return rs;
    }

    /**
     * 订单列表
     * @param param 查询参数
     * @return Response<Page<OrderDTO>>
     */
    @PostMapping("/list")
    @ApiOperation(value = "订单列表", notes = "订单列表", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<Page<OrderDTO>> list(@RequestBody OrderQueryParam param) {
        try {
            return orderFeignService.listOrder(param);
        } catch (Exception e) {
            log.error("查询订单列表异常" + "[" + e.getMessage() + "]");
            return Response.failed("查询订单列表异常" + e.getMessage());
        }
    }

    /**
     * 订单详情
     * @param params{orderId-订单ID,longitude-当前定位经度,latitude-当前定位维度}
     * @return Response<OrderDTO>
     */
    @PostMapping("/detail")
    @ApiOperation(value = "订单详情", notes = "订单详情", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<OrderDTO> detail(@RequestBody Map<String,Object> params) {
        try {
            return orderFeignService.viewOrder(Long.parseLong((String) params.get("orderId")));
//            if(null != rs && rs.getCode() == 200 && null != rs.getData()){
//                OrderDTO order = rs.getData();
//                if(order.getAddressId() == null) {
//                    order.setDistance(LBSUtil.getDistanceByLongitudeAndLatitude(order.getStoreLongitude().doubleValue(),order.getStoreLatitude().doubleValue(),Double.valueOf((String)params.get("longitude")),Double.valueOf((String)params.get("latitude"))));
//                }
//            }
//            return rs;
        } catch (Exception e) {
            log.error("查询订单详情异常" + "[" + e.getMessage() + "]");
            return Response.failed("查询订单详情异常" + e.getMessage());
        }
    }

    /**
     * 根据店铺和会员ID分页获取订单列表
     * @param paramMap{"storeId":123,"userCode": 12321, "pageNumber": 1, "pageSize": 10}
     *                分页参数选填，默认pageNumber=1,pageSize=10
     * @return Response<Page<OrderDTO>>
     */
    @PostMapping("/listByStoreIdAndMemberId")
    @ApiOperation(value = "根据店铺和会员ID分页获取订单列表", notes = "根据店铺和会员ID分页获取订单列表", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<Page<OrderDTO>> listByStoreIdAndMemberId(@RequestBody Map<String,Object> paramMap) {
        try {
            StoreOrderQueryParam param = new StoreOrderQueryParam();
            if (null == paramMap || null == paramMap.get("storeId") || null == paramMap.get("userCode")) {
                return Response.failed("非法请求,请求参数错误！");
            } else {
                // 默认待核销的
                param.setStatus(3);
                if (null != paramMap.get("pageNumber")) {
                    param.setPageNumber(paramMap.get("pageNumber").toString());
                }
                if (null != paramMap.get("pageSize")) {
                    param.setPageSize(paramMap.get("pageSize").toString());
                }
                param.setStoreId(Long.valueOf(paramMap.get("storeId").toString()));
                String decryptStr = AESUtil.decrypt(paramMap.get("userCode").toString());
                String[] arr = decryptStr.split(":");
                param.setMemberId(Long.parseLong(arr[0]));
                // 只查找当前可以核销的订单
                param.setEndTime(LocalDateTime.now().withHour(22).withMinute(0).withSecond(0));
                return orderFeignService.listStoreOrder(param);
            }
        } catch (Exception e) {
            log.error("根据店铺和会员ID分页获取订单列表异常" + "[" + e.getMessage() + "]");
            return Response.failed("根据店铺和会员ID分页获取订单列表异常" + e.getMessage());
        }
    }

    /**
     * 店铺订单列表（按创建时间排序）
     * @param param 查询参数
     * @return Response<Page<OrderDTO>>
     */
    @PostMapping("/store/list")
    @ApiOperation(value = "店铺订单按创建时间排序列表", notes = "店铺订单按创建时间排序列表", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<Page<OrderDTO>> listStoreOrder(@RequestBody StoreOrderQueryParam param) {
        try {

            if (param == null || param.getStoreId() == null) {
                return Response.failed("非法请求");
            }

            Response<Page<OrderDTO>> rs = orderFeignService.listStoreOrder(param);
            if(null != rs && rs.getCode() == 200 && null != rs.getData()){
                rs.getData().getRecords().forEach(item -> {
                    if(item.getAddressId() == null) {
                        item.setDistance(LBSUtil.getDistanceByLongitudeAndLatitude(item.getStoreLongitude().doubleValue(),item.getStoreLatitude().doubleValue(),param.getLongitude(),param.getLatitude()));
                    }
                });
            }
            return rs;
        } catch (Exception e) {
            log.error("查询订单列表异常" + "[" + e.getMessage() + "]");
            return Response.failed("查询订单列表异常" + e.getMessage());
        }
    }

    /**
     * 店铺订单列表（按提货时间排序）
     * @param param 查询参数
     * @return Response<Page<OrderDTO>>
     */
    @PostMapping("/store/listByDeliveryTime")
    @ApiOperation(value = "店铺订单按提货时间排序列表", notes = "店铺订单按提货时间排序列表", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<Page<OrderDTO>> listStoreOrderByDeliveryTime(@RequestBody StoreOrderQueryParam param) {
        try {
            if (param == null || param.getStoreId() == null) {
                return Response.failed("非法请求");
            }
            return orderFeignService.listStoreOrderByDeliveryTime(param);
        } catch (Exception e) {
            log.error("查询订单列表异常" + "[" + e.getMessage() + "]");
            return Response.failed("查询订单列表异常" + e.getMessage());
        }
    }

    /**
     * 更新订单状态订单
     * @param param 更新参数
     * @return Response<OrderDTO>
     */
    @PostMapping("/update/status")
    @ApiOperation(value = "更新订单状态", notes = "更新订单状态", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<OrderDTO> updateOrderStatus(@RequestBody OrderMainStatusUpdateParam param) {
        try {

            if (param == null) {
                return Response.failed("非法请求");
            }

            return orderFeignService.updateOrderStatus(param);
        } catch (Exception e) {
            log.error("更新订单状态异常" + "[" + e.getMessage() + "]");
            return Response.failed("更新订单状态失败" + e.getMessage());
        }
    }

    /**
     * 查询商品购买记录
     * @param param 查询参数
     * @return Response<Map<String,Object>>
     */
    @PostMapping("/queryOrdersWithUserInfo")
    @ApiOperation(value = "查询商品购买记录", notes = "查询商品购买记录", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<Page<Map<String,Object>>> queryOrdersWithUserInfo(@RequestBody OrderQueryParam param){
        try {
            return orderFeignService.queryOrdersWithUserInfo(param);
        } catch (Exception e) {
            log.error("查询商品购买记录异常" + "[" + e.getMessage() + "]");
            return Response.failed("查询商品购买记录异常" + e.getMessage());
        }
    }

    /**
     * 查询当前登录用户历史收货人和电话
     * @param userId 用户ID
     * @return Response<List<Map<String,Object>>>
     */
    @PostMapping("/getHistoryConsigneeAndTelephone/{userId}")
    @ApiOperation(value = "查询用户历史收货人和电话", notes = "查询用户历史收货人和电话记录", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<List<Map<String,Object>>> getHistoryConsigneeAndTelephone(@PathVariable("userId") Long userId) {
        Response<List<Map<String,Object>>> rs;
            try {
                OrderMainQueryParam param = new OrderMainQueryParam();
                param.setMemberId(userId);
                param.setOrderStatus(2);
                Response<List<OrderMain>> orders = orderFeignService.listOrderMainInfos(param);
                List<Map<String,Object>> list = new ArrayList<>();
                if (null != orders && orders.getCode() == 200 && orders.getData().size() > 0) {
                    orders.getData().forEach( item ->{
                        Map<String,Object> map = new HashMap<>();
                        map.put("consignee",item.getConsignee());
                        map.put("telephone",item.getMobile());
                        list.add(map);
                    });
                    rs = Response.data(list.stream().distinct().collect(Collectors.toList()));
                } else {
                    rs = Response.failed("没有查询到当前用户购买历史");
                }
            } catch (Exception e) {
              log.error("查询用户历史收货人和电话异常 {}", e.getMessage());
              rs = Response.failed("查询用户历史收货人和电话异常");
            }
        return rs;
    }

    /**
     * 一键提醒当天及以前可提货的买家
     * @param storeId 店铺ID
     * @return Response<String>
     */
    @GetMapping("/notifyBuyersByStoreId/{storeId}")
    @ApiOperation(value = "一键提醒当天及以前可提货的买家", notes = "一键提醒当天及以前可提货的买家", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<String> notifyBuyersByStoreId(@PathVariable("storeId") Long storeId) {
        Response<String> rs;
        try {
            // 查询今天可以提货的订单
            StoreOrderQueryParam param = new StoreOrderQueryParam();
            param.setStoreId(storeId);
            param.setStatus(3);
            param.setPickUpTime(LocalDateTime.now().withHour(23).withMinute(59).withSecond(59));
            Response<List<OrderMain>> orderMainResponse = orderFeignService.listCanPickUpStoreOrder(param);
            if (null != orderMainResponse && orderMainResponse.getCode() == 200 && null != orderMainResponse.getData()) {
                // 多个手机号码
                StringBuffer mobile = new StringBuffer();
                orderMainResponse.getData().forEach(item -> mobile.append(item.getMobile()).append(","));
                // 查找对应店铺联系电话
                Response<PlatStoreDTO> storeResponse = userFeignService.queryById(storeId);
                if (null != storeResponse && storeResponse.getCode() == 200 && null != storeResponse.getData()) {
                    // 模板参数
                    Map<String,Object> map = new HashMap<>();
                    map.put("phone",storeResponse.getData().getMobile());
                    // 调用短信发送服务，发送提醒短信
                    Response send_rs = veriCenterFeignService.batchSendTplMsg(mobile.toString().substring(0,mobile.length()-1), JSON.toJSONString(map),"3162904");
                    if (null != send_rs && send_rs.getCode() == 200 && null != send_rs.getData()) {
                        rs = Response.data(String.valueOf(send_rs.getData()));
                    } else {
                        rs = Response.failed("提醒可提货订单的买家失败，发送短信失败");
                    }
                } else {
                    rs = Response.failed("提醒失败，没有找到对应的订单的店铺信息");
                }
            } else {
                rs = Response.failed("提醒失败，没有找到对应的订单信息");
            }
        } catch (Exception e) {
            log.error("提醒失败："+e.getMessage());
            rs = Response.failed("提醒失败，系统出错");
        }
        return rs;
    }

    /**
     * 提醒待提货订单的买家
     * @param orderId 订单ID
     * @return Response<String>
     */
    @GetMapping("/notifyBuyerByOrderId/{orderId}")
    @ApiOperation(value = "提醒待提货订单的买家", notes = "一键提醒当天及以前待提货的买家", consumes = MediaType.APPLICATION_JSON_VALUE)
    public Response<String> notifyBuyerByOrderId(@PathVariable("orderId") Long orderId) {
        Response<String> rs;
        try {
            Response<OrderMain> orderMainResponse = orderFeignService.getOrderMainById(orderId);
            if (null != orderMainResponse && orderMainResponse.getCode() == 200 && null != orderMainResponse.getData()) {
                // 查找对应店铺联系电话
                Response<PlatStoreDTO> storeResponse = userFeignService.queryById(orderMainResponse.getData().getStoreId());
                if (null != storeResponse && storeResponse.getCode() == 200 && null != storeResponse.getData()) {
                    // 模板参数
                    Map<String,Object> map = new HashMap<>();
                    map.put("phone",storeResponse.getData().getMobile());
                    // 调用短信发送服务，发送提醒短信
                    Response send_rs = veriCenterFeignService.sendTplMsg(orderMainResponse.getData().getMobile(), JSON.toJSONString(map),"3162904");
                    if (null != send_rs && send_rs.getCode() == 200 && null != send_rs.getData()) {
                        rs = Response.data((String)send_rs.getData());
                    } else {
                        rs = Response.failed("提醒可提货订单的买家失败，发送短信失败");
                    }
                } else {
                    rs = Response.failed("提醒失败，没有找到对应的订单的店铺信息");
                }
            } else {
                rs = Response.failed("提醒失败，没有找到对应的订单信息");
            }
        } catch (Exception e) {
            log.error("提醒失败："+e.getMessage());
            rs = Response.failed("提醒失败，系统出错");
        }
        return rs;
    }
}
